Skip to content

FIX: Add /ship skill for branch, atomic commits, and draft PR workflow#76

Open
tahierhussain wants to merge 6 commits intomainfrom
fix/claude-ship-skill
Open

FIX: Add /ship skill for branch, atomic commits, and draft PR workflow#76
tahierhussain wants to merge 6 commits intomainfrom
fix/claude-ship-skill

Conversation

@tahierhussain
Copy link
Copy Markdown
Contributor

@tahierhussain tahierhussain commented Apr 28, 2026

What

Adds a new manual-only Claude Code skill at .claude/skills/ship/ that
walks uncommitted (or already-committed) changes through a structured
flow: branch creation → atomic Conventional-Commits → push → draft PR.
The skill is composed of SKILL.md (the procedure) and
pr-body-template.md (the source-of-truth PR description template).

Why

Standardises how PRs get raised from this working directory so branch
names, commit grouping, and PR descriptions stay consistent across
sessions, without relying on memory or ad-hoc prompting. Manual-only
(disable-model-invocation: true) so it never auto-fires from
conversational pattern-matching — it only runs when explicitly
invoked via /ship.

How

Two new files under .claude/skills/ship/:

  • SKILL.md defines six phases (discover/classify, plan branch name,
    plan commits with confirmation gate, execute, draft PR body with
    confirmation gate, raise PR), plus rules for branch prefixes (binary
    feat/ vs fix/), commit grouping, secrets scanning, and PR-section
    source mapping.
  • pr-body-template.md is the canonical PR body template the skill
    reads on every run, so future structural changes to PR descriptions
    are made by editing the template alone.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

No runtime impact. The change is purely additive Claude Code tooling
under .claude/skills/ — no application code, build config, CI
workflow, or product surface is touched. The skill is gated behind
manual /ship invocation, so it cannot auto-trigger.

Database Migrations

None.

Env Config

None.

Relevant Docs

None.

Related Issues or PRs

None.

Dependencies Versions

None.

Notes on Testing

  • Run /ship on a clean working tree on main and confirm it stops with a clear "no changes" message
  • Run /ship with mixed feat + fix changes and confirm it asks whether to split before proceeding
  • Run /ship with a staged file containing a fake sk-… token and confirm the secrets-scan hard-stop fires before any commit
  • Run /ship end-to-end on a small change and confirm the draft PR is opened with the body sourced from pr-body-template.md (not .github/)
  • Confirm a pre-commit hook failure surfaces the error and stops, with no --no-verify retry and no amend
  • Confirm the skill never auto-invokes from conversational phrasing (disable-model-invocation: true honoured)

Screenshots

N/A — tooling-only change, no UI surface.

Checklist

I have read and understood the Contribution Guidelines.

Adds a manual-only Claude Code skill that walks uncommitted changes
through branch creation, atomic commits, push, and draft PR. Includes
the project's PR body template as the source of truth for PR descriptions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tahierhussain tahierhussain self-assigned this Apr 28, 2026
@tahierhussain tahierhussain added the documentation Improvements or additions to documentation label Apr 28, 2026
@tahierhussain tahierhussain marked this pull request as ready for review April 28, 2026 10:12
@tahierhussain tahierhussain requested a review from a team as a code owner April 28, 2026 10:12
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 28, 2026

Greptile Summary

This PR adds a manual-only /ship Claude Code skill that automates the branch → atomic commits → push → draft PR workflow, along with a canonical PR body template. All previously flagged issues (missing AskUserQuestion in allowed-tools, broken gh pr create continuation, hardcoded --base main, temp-file path collisions for feat//fix/ branches, secrets scan gaps for staged/untracked files, and the contradictory secrets-menu option 2) have been addressed in the current revision.

Confidence Score: 5/5

Safe to merge — no runtime impact, purely additive tooling with all prior P1 issues resolved.

Only P2 findings remain (xargs -r portability on macOS and a hardcoded model version string). No application code, build config, or CI is touched.

No files require special attention.

Important Files Changed

Filename Overview
.claude/skills/ship/SKILL.md Comprehensive skill definition with well-structured phases, confirmation gates, and secrets scanning; all previously flagged P1 issues resolved; two minor P2 items remain (xargs -r portability and hardcoded model version in Co-Authored-By trailer).
.claude/skills/ship/pr-body-template.md Clean PR body template matching the project's required sections; no issues found.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A(["/ship invoked"]) --> B[Phase 1: Discover & Classify\ngit status / diff HEAD / ls-files]
    B --> C{Changes?}
    C -- "None on main/master/develop" --> Z1([Stop: no changes])
    C -- "Already committed" --> SEC1[Secrets scan\ngit diff base...HEAD]
    C -- "Uncommitted" --> SEC2[Secrets scan\ngit diff HEAD + untracked files]
    SEC1 --> SEC_GATE{Hit?}
    SEC2 --> SEC_GATE
    SEC_GATE -- "Yes" --> AUQ[AskUserQuestion:\nDrop / Remove / Cancel]
    AUQ --> Z2([Stop or continue clean])
    SEC_GATE -- "No" --> D{feat / fix / mixed?}
    D -- "Mixed" --> GATE0[Gate 0: split PRs?]
    D -- "Clear" --> E[Phase 2: Plan branch name\nfeat/ or fix/]
    GATE0 --> E
    E --> F[Phase 3: Plan atomic commits]
    F --> GATE1{Gate 1: confirm plan?}
    GATE1 -- "No" --> Z3([Abort])
    GATE1 -- "Yes" --> G[Phase 4: Execute\ngit checkout -b\ngit add + commit x N\ngit push -u origin]
    G --> H[Phase 5: Draft PR body\nread pr-body-template.md]
    H --> GATE2{Gate 2: confirm body?}
    GATE2 -- "No" --> Z4([Abort])
    GATE2 -- "Yes" --> I[Phase 6: Raise PR\ngh auth check\ncheck existing PR\nsanitize branch name\nwrite /tmp body\ngh pr create --draft\nclean up temp file]
    I --> J([Print PR URL])
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
.claude/skills/ship/SKILL.md:108-113
`xargs -r` (`--no-run-if-empty`) is a GNU coreutils extension — it does not exist in macOS's BSD `xargs`. When there are no untracked files, the empty-input pipeline on macOS causes `xargs` to exit with a "illegal option" error (exit code non-zero). With `2>/dev/null` suppressing the message but not the exit code, Claude's Bash tool would see a failure here and may abort the workflow or silently skip the untracked-file scan, defeating the hard-stop guarantee. Replacing `-r` with an explicit emptiness guard is portable across macOS and Linux.

```suggestion
A combined invocation:
```bash
git diff HEAD | grep -E '<patterns>'
UNTRACKED=$(git ls-files --others --exclude-standard 2>/dev/null)
[ -n "$UNTRACKED" ] && echo "$UNTRACKED" | xargs grep -EIn '<patterns>' 2>/dev/null || true
```
```

### Issue 2 of 2
.claude/skills/ship/SKILL.md:31-32
The `Co-Authored-By` trailer hard-codes `Claude Opus 4.7 (1M context)`, which will become stale as soon as a newer model handles this skill. Every commit made from this skill at that point carries an inaccurate attribution. Consider using a version-agnostic label (e.g., `Claude Code`) so the trailer remains accurate indefinitely without needing edits to this file.

```suggestion
**Commit trailer:** Every commit message ends with the trailer
`Co-Authored-By: Claude Code <noreply@anthropic.com>`,
```

Reviews (6): Last reviewed commit: "fix(claude): scan untracked files in /sh..." | Re-trigger Greptile

Comment thread .claude/skills/ship/SKILL.md
Comment thread .claude/skills/ship/SKILL.md Outdated
Comment thread .claude/skills/ship/SKILL.md Outdated
…n /ship skill

- Fix line-continuation bug in the Phase 6 gh pr create example: move the
  FEAT/FIX note above the block so every flag carries a backslash.
- Resolve --base dynamically via `gh repo view` so the skill works on
  repos whose default branch is not `main`.
- Add `AskUserQuestion` to allowed-tools so the secrets-scan hard-stop
  can present its structured three-option prompt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread .claude/skills/ship/SKILL.md Outdated
Branch names always contain a `/` (feat/<kebab> or fix/<kebab>), so
`/tmp/pr-body-<branch>.md` resolved to a non-existent subdirectory and
broke the write, --body-file, and cleanup steps. Sanitize via
`tr '/' '-'` into `$BRANCH_SAFE` and thread it through all three.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread .claude/skills/ship/SKILL.md Outdated
Comment thread .claude/skills/ship/SKILL.md Outdated
- Drop unused Edit from allowed-tools.
- Document the Co-Authored-By trailer in commit-format conventions.
- Tighten the AWS secret-key scan to assignment + 40-char value so
  bare references in .env.example don't trip the gate.
- Reorder Phase 6 so gh auth status runs before any temp-file write,
  add an existing-PR check that stops with the URL surfaced (no silent
  gh pr create failure on re-runs), make the title prefix derive from
  classification instead of hard-coded FEAT, and switch cleanup to rm -f.
- Require every '-' placeholder from the PR-body template to be
  replaced with prose or a literal TODO before raising.
- Update Section 9 to describe the existing-PR stop behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread .claude/skills/ship/SKILL.md Outdated
Edge case "no uncommitted changes" previously said to skip Phases 1-4
wholesale, which silently bypassed the secrets-scan hard stop in Phase 1
and contradicted the Section 8 guardrail. Now the scan still runs against
`git diff <base>...HEAD` on this path; only the commit-planning steps
(Phases 2-3) are skipped if the scan comes back clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread .claude/skills/ship/SKILL.md Outdated
`git diff HEAD` only covers tracked files — net-new files (those with `??`
in `git status`, never `git add`-ed) were invisible to the secrets scan,
so a brand-new `secrets.py` containing `sk-…` could be planned in Phase 3,
staged in Phase 4, and committed without ever hitting the hard stop.

Phase 1 now lists untracked files via `git ls-files --others --exclude-standard`
and scans them in full as a second surface alongside the tracked diff.
The hit-handling AskUserQuestion options are extended with untracked-file
equivalents (don't `git add` instead of `git restore --staged`; plain `rm`
instead of `git rm`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@wicky-zipstack wicky-zipstack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants